package com.yanqu.road.server.manger.activity.advertisement;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.advertisement.AdvertisementSystemData;
import com.yanqu.road.entity.activity.advertisement.config.AdvertisementConfig;
import com.yanqu.road.entity.activity.advertisement.config.AdvertisementSystemConfig;
import com.yanqu.road.entity.enums.activity.advertisement.eAdvertisementSystemId;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.logic.bussiness.activity.AdvertisementActivityBusiness;
import com.yanqu.road.pb.activity.AdvertisementProto;
import com.yanqu.road.pb.activity.RecoveryRewardProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.advertisement.AdvertisementActivityModule;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class AdvertisementActivityMgr extends TempMgr {

    private static ActivityInfo activityInfo;

    private static AdvertisementConfig config;

    @Override
    public boolean init() throws Exception {
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static void reloadActivityData() {
        getLogger().info("reload advertisement activity start");
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.Advertisement.getValue());
        if (openActivityInfoList.isEmpty()){
            getLogger().info("reload advertisement activity finish, no activity in show time.");
            config = null;
            activityInfo = null;
            return;
        }
        ActivityInfo tmpActivityInfo = openActivityInfoList.get(0);
        //活动配置
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(tmpActivityInfo.getActivityId());
        activityInfo = tmpActivityInfo;
        Map<Integer, AdvertisementSystemConfig> tmpConfig = AdvertisementActivityBusiness.getAdvertisementConfigMap(activityInfo.getActivityId());
        config = new AdvertisementConfig(tmpConfig,activityConfigMap);

        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            AdvertisementActivityModule module = player.getModule(AdvertisementActivityModule.class);
            module.syncConfig();
            module.checkAll();
            module.syncData();
        }

        getLogger().info("reload advertisement activity finish");
    }

    public static ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public static AdvertisementConfig getConfig() {
        return config;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static int checkCanWatchAdvertisement(AdvertisementSystemData systemData) {
        if (config == null){
            return GameErrorCode.E_ADVERTISEMENT_ACTIVITY_NO_OPEN;
        }
        AdvertisementSystemConfig systemConfig = config.getSystemConfigMap().get(systemData.getSystemId());
        if (systemConfig == null){
            return GameErrorCode.E_ADVERTISEMENT_ACTIVITY_NO_SYSTEM;
        }

        if (systemConfig.getButtonFinish() != 0){
            int serverOpenDay = ServerListMgr.getServerOpenDay(GameServer.getInstance().getServerId());
            if (systemConfig.getButtonFinish() < serverOpenDay){
                return GameErrorCode.E_ADVERTISEMENT_ACTIVITY_NO_OPEN_DAY;
            }
        }

        long now = System.currentTimeMillis();
        //判断先用这个来判断 设置开始时间得用客户端的时间
        if ((systemData.getLastWatchTime() + systemConfig.getCoolCd() * DateHelper.SECOND_MILLIONS) > now){
            return GameErrorCode.E_ADVERTISEMENT_ACTIVITY_IN_COOL_CD;
        }
        if (systemConfig.getNumMax() != -1){        //次数限制 -1为无限制
            if (systemData.getHasWatchTimes() >= systemConfig.getNumMax()){
                return GameErrorCode.E_ADVERTISEMENT_ACTIVITY_WATCH_MAX;
            }
        }
        return 0;
    }

    public static Map<Integer,Integer> getInitTotalWatchMap(){
        if (config == null){
            return null;
        }
        Map<Integer,Integer> totalWatchMap = new ConcurrentHashMap<>();
        for (AdvertisementSystemConfig systemConfig:config.getSystemConfigMap().values()){
            totalWatchMap.put(systemConfig.getSystemId(),0);
        }
        return totalWatchMap;

    }

    public static Map<Integer, AdvertisementSystemData> getInitAdvertisementSystemDataMap() {
        if (config == null){
            return null;
        }
        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        long now = System.currentTimeMillis();
        Map<Integer, AdvertisementSystemData> advertisementSystemDataMap = new ConcurrentHashMap<>();
        for (AdvertisementSystemConfig systemConfig:config.getSystemConfigMap().values()){
            AdvertisementSystemData systemData = new AdvertisementSystemData();
            systemData.setSystemId(systemConfig.getSystemId());
            systemData.setHasWatchTimes(0);
            systemData.setLastRefreshLimitTime(now);
            systemData.setLastWatchTime(0);
            if(systemConfig.getSystemId() == eAdvertisementSystemId.Login.getValue() || systemConfig.getSystemId() == eAdvertisementSystemId.SevenSign.getValue()){
                systemData.setLastRefreshLimitTime(todayZeroTimeStamp);
            }
            advertisementSystemDataMap.put(systemConfig.getSystemId(),systemData);
        }
        return advertisementSystemDataMap;
    }

    public static AdvertisementProto.AdvertisementConfigSyncMsg.Builder getConfigBuilder(String language) {
        AdvertisementProto.AdvertisementConfigSyncMsg.Builder builder = AdvertisementProto.AdvertisementConfigSyncMsg.newBuilder();
        if (config == null){
            return builder;
        }
        for (AdvertisementSystemConfig systemConfig:config.getSystemConfigMap().values()){
            AdvertisementProto.AdvertisementConfig.Builder configBuilder = AdvertisementProto.AdvertisementConfig.newBuilder();
            configBuilder.setId(systemConfig.getSystemId());
            configBuilder.setName(ServerLanguageMgr.getContent(systemConfig.getName(),language));
            configBuilder.setOrder(systemConfig.getOrder());
            configBuilder.setButtonFinish(systemConfig.getButtonFinish());
            configBuilder.setNumMax(systemConfig.getNumMax());
            configBuilder.setCoolCd(systemConfig.getCoolCd());
            configBuilder.setReward(systemConfig.getReward());
            configBuilder.setSpecialReward(systemConfig.getSpecialReward());
            configBuilder.setShopId(systemConfig.getShopId());
            builder.addAdvertisementConfig(configBuilder);
        }
        return builder;
    }

    /**
     * 获取现在npc在每日第几阶段
     */
    public static List<Long> getNpcStageAndRefreshTime(){
        if(activityInfo == null){
            return null;
        }
        if (config == null){
            return null;
        }
        List<Long> npcStageList = new ArrayList<>();

        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        long now = System.currentTimeMillis();

        long diff = now - todayZeroTimeStamp;

        long stage = diff / (config.getShopNpcRefreshCd() * DateHelper.HOUR_MILLIONS);
        long hasPassTime = diff % (config.getShopNpcRefreshCd() * DateHelper.HOUR_MILLIONS);

        npcStageList.add(stage);
        npcStageList.add(now-hasPassTime);

        return npcStageList;
    }

    /**
     * 获取随机商铺小人奖励
     */
    public static String randomNpcReward(){
        if(activityInfo == null){
            getLogger().error("advertisement randomNpcReward error, activity no exist {}",activityInfo.getActivityId());
            return null;
        }
        if (config == null){
            getLogger().error("advertisement randomNpcReward config error{}",activityInfo.getActivityId());
            return null;
        }
        AdvertisementSystemConfig systemConfig = config.getSystemConfigMap().get(eAdvertisementSystemId.buildingNpc.getValue());
        if (systemConfig == null){
            getLogger().error("advertisement randomNpcReward error, no systemConfig,activityId {}",activityInfo.getActivityId());
            return null;
        }
        int index = RandomHelper.getRandomIndexByWeight(config.getShopNpcRefreshWeight());

        String reward = systemConfig.getReward();
        List<String> stringList = StringUtils.stringToStringList(reward, "\\|");
        if (stringList.size() == 0){
            getLogger().error("advertisement randomNpcReward data error, no systemConfig,activityId {}",activityInfo.getActivityId());
            return null;
        }
        if (index < 0 || index > stringList.size()-1){
            return stringList.get(0);
        }
        return stringList.get(index);

    }

    /**
     * 合并广告消息 只有小玉调用的可以用这个方法！！ 没有合并手动的广告游历和盗墓
     */
    public static AdvertisementProto.WatchAdvertisementOverRespMsg.Builder mergeAssistAdvertisementRespMsg(AdvertisementProto.WatchAdvertisementOverRespMsg.Builder builder, AdvertisementProto.WatchAdvertisementOverRespMsg.Builder builder2) {
        if (builder == null && builder2 == null){
            return null;
        }

        if (builder2 == null){
            return builder;
        }
        if (builder == null){
            return builder2;
        }
        //如果第二次请求有错误马，就不合并了
        if (builder2.getRet() != 0){
            return builder;
        }
        //新建一个合并完的builder
        AdvertisementProto.WatchAdvertisementOverRespMsg.Builder mergeBuilder = AdvertisementProto.WatchAdvertisementOverRespMsg.newBuilder();
        //合并错误码
        mergeBuilder.setRet(0);
        //玩家数据用新的玩家数据覆盖旧的
        mergeBuilder.setUserdata(builder2.getUserdata());
        //合并普通奖励
        if (builder.hasNormalReward() && builder2.hasNormalReward()){
            //拿出第一个普通奖励
            Property property = PropertyHelper.parseStringToProperty(builder.getNormalReward());
            //拿出第二个普通奖励
            Property property2 = PropertyHelper.parseStringToProperty(builder2.getNormalReward());
            //合并普通奖励
            property.addProperty(property2);
            //赋值给结果
            mergeBuilder.setNormalReward(PropertyHelper.parsePropertyToString(property));
        }else if (builder.hasNormalReward()){
            mergeBuilder.setNormalReward(builder.getNormalReward());
        }else if (builder2.hasNormalReward()){
            mergeBuilder.setNormalReward(builder2.getNormalReward());
        }
        //合并游历的奖励
        if (builder.hasTravelResp() && builder2.hasTravelResp()){
            //如果只有其中一个错误码为0 就取那个当结果
            RecoveryRewardProto.RecoverTravelGoRespMsg travelResp = builder.getTravelResp();
            RecoveryRewardProto.RecoverTravelGoRespMsg travelResp2 = builder2.getTravelResp();
            if (travelResp.getRet() == 0 && travelResp2.getRet() != 0){
                mergeBuilder.setTravelResp(travelResp);
            } else if (travelResp.getRet() != 0 && travelResp2.getRet() == 0){
                mergeBuilder.setTravelResp(travelResp2);
            } else if (travelResp.getRet() == 0 && travelResp2.getRet() == 0){
                RecoveryRewardProto.RecoverTravelGoRespMsg.Builder travelRespBuilder = RecoveryRewardProto.RecoverTravelGoRespMsg.newBuilder();
                travelRespBuilder.setRet(0);
                //合并游历的结果
                travelRespBuilder.addAllSelectObjectList(travelResp.getSelectObjectListList());
                travelRespBuilder.addAllSelectObjectList(travelResp2.getSelectObjectListList());
                //合并city
                travelRespBuilder.addAllEventIdList(travelResp.getEventIdListList());
                travelRespBuilder.addAllEventIdList(travelResp2.getEventIdListList());
                //合并最后到达
                if (travelResp.hasCityId()){
                    travelRespBuilder.setCityId(travelResp.getCityId());
                }
                if (travelResp2.hasCityId()){
                    travelRespBuilder.setCityId(travelResp2.getCityId());
                }
                mergeBuilder.setTravelResp(travelRespBuilder);
            }
        }else if (builder.hasTravelResp()){
            mergeBuilder.setTravelResp(builder.getTravelResp());
        }else if (builder2.hasTravelResp()){
            mergeBuilder.setTravelResp(builder2.getTravelResp());
        }

        //合并抽奖特殊奖励
        List<String> lotteryRewardList = builder.getLotteryRewardList();
        List<String> lotteryRewardList2 = builder2.getLotteryRewardList();

        if (lotteryRewardList.size()>0 && lotteryRewardList2.size()>0){
            List<String> totalReward = new ArrayList<>();
            //合并普通奖励
            totalReward.addAll(lotteryRewardList);
            totalReward.addAll(lotteryRewardList2);
            //赋值给结果
            mergeBuilder.addAllLotteryReward(totalReward);
        }else if (lotteryRewardList.size()>0){
            mergeBuilder.addAllLotteryReward(lotteryRewardList);
        }else if (lotteryRewardList2.size()>0){
            mergeBuilder.addAllLotteryReward(lotteryRewardList2);
        }

        //盗墓不处理 不会合并的

        //手动也不合并



        return mergeBuilder;
    }


}
